package com.uminho.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.MonthDisplayHelper;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.markupartist.android.widget.ActionBar;
import com.markupartist.android.widget.ActionBar.Action;
import com.uminho.calendar.CalendarView;
import com.uminho.calendar.Cell;
import com.uminho.egendme.R;
import com.uminho.exceptions.InvalidOAuthParametersError;
import com.uminho.exceptions.InvalidOAuthTokenError;
import com.uminho.http.InternalStorage;
import com.uminho.http.Webservice;
import com.uminho.objects.Appointment;
import com.uminho.objects.Service;
import com.uminho.tools.Disponibilidades;

/****c* ServiceCalendar/ServiceCalendar
 * DESCRIPTION
 * Implementa o calendário.
 ****
 */
public class ServiceCalendar extends Activity implements CalendarView.OnCellTouchListener{
	//private long serviceId=-1;
	//private long bookmarkId=-1;
	GregorianCalendar dayloaded=null;
	private Service servico=null;
	CalendarView mView = null;
	TextView mHit;
	Handler mHandler = new Handler();
	TextView actualMonthTitle, lastMonthTitle, nextMonthTitle;
	ImageView prev, next;
	Button confirmDialog;
	HashMap<Date,Integer> infoCalendars;
	ProgressDialog myProgressDialog = null; 
	Handler messages=null;
	ArrayList<Appointment> slots;
	int day, month, year;
	boolean offline=false;
	String[] monthName = {"January", "February",
  		  "March", "April", "May", "June", "July",
  		  "August", "September", "October", "November",
  		  "December"
  };
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.calendar_table_layout);
		ActionBar actionBar = (ActionBar) findViewById(R.id.actionbar);
		actionBar.setHomeAction(new Action() {
			
			public void performAction(View view) {
				ServiceCalendar.this.setResult(4);
				ServiceCalendar.this.finish();
			}
			
			public int getDrawable() {
				return R.drawable.icon1;
			}
		});
		actionBar.setTitle(R.string.service_calendar);
		dayloaded=new GregorianCalendar();
  		servico= (Service) getIntent().getExtras().get("service");
		Log.d("CAL1-servico null?","servico "+servico.getName());		       
		Log.d("CAL2-servico null?", ""+servico.getId());	
		
		mView = (CalendarView)findViewById(R.id.calendar);
		
		
        if(Disponibilidades.serviceBusyDays==null){
            infoCalendars = new HashMap<Date,Integer>();
            mView.setBusyDays(infoCalendars);
            Log.d("Calendar service disponibilidades", "vazias!!!!");
    		}
        else{
        	Log.d("Calendar service disponibilidades", "Com elementos!!!!");
        	mView.setBusyDays(Disponibilidades.serviceBusyDays);
        }
       
		
        mView.setOnCellTouchListener(this);
        
       
        //set month title
        actualMonthTitle = (TextView) findViewById(R.id.textViewCalendarMonth);
        actualMonthTitle.setText(monthName[mView.getMonth()]+", "+mView.getYear());
      
        
        MonthDisplayHelper calendarAux = new MonthDisplayHelper(mView.getYear(), mView.getMonth());
        calendarAux.previousMonth();
        
        initHandler();
        
        prev = (ImageView) findViewById(R.id.prev);
        prev.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				mView.previousMonth();
				//onTouch(null);
				if(dayloaded.get(GregorianCalendar.YEAR)==mView.getYear()){
					onTouch(null);
				}
				else{
					//caregar ano anterior  de disponibilidades
					messages.sendEmptyMessage(21);
				}
			}
		}
		);
        
        calendarAux.nextMonth();
        calendarAux.nextMonth();
        
        next = (ImageView) findViewById(R.id.next);
        next.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				mView.nextMonth();
				//onTouch(null);
				if(dayloaded.get(GregorianCalendar.YEAR)==mView.getYear()){
					onTouch(null);
				}
				else{
					//caregar novo ano de disponibilidades
					messages.sendEmptyMessage(20);
				}
			}
		}
		);
		
	}
	
	
	private void initHandler(){
		if(messages==null){
	        messages = new Handler() {
		        @Override
				public void handleMessage(Message msg) {
		        	if(msg.what==1){
						if(offline) Toast.makeText(ServiceCalendar.this, getString(R.string.working_offline), 3000).show();
		        		boolean future = true;
						GregorianCalendar today = new GregorianCalendar();
						//ano anterior
						if(year<today.get(GregorianCalendar.YEAR)) future=false;
						//mesmo ano mes anterior
						else if(year==today.get(GregorianCalendar.YEAR) && 
								month<today.get(GregorianCalendar.MONTH)) future=false;
						//mesmo ano, mesmo mes, dia inferior
						else if(year==today.get(GregorianCalendar.YEAR) && 
								month==today.get(GregorianCalendar.MONTH) && 
								day<today.get(GregorianCalendar.DAY_OF_MONTH)) future=false;;
						
						if(future){
							
						
						//Service Day
						Intent intent = new Intent(ServiceCalendar.this,
								ServiceDay.class);
						Bundle b = new Bundle();
						//id of service
						b.putLong("servicokey", servico.getId());
						//id of bookmarker
						b.putLong("servicoyear", year);
						b.putLong("servicomonth", month);
						b.putLong("servicoday", day);
						intent.putExtra("service", servico);
						intent.putExtras(b);
						startActivityForResult(intent, 0);
						}
						else{
							//day before
			        		Toast.makeText(ServiceCalendar.this, getString(R.string.dayoutofbounds), Toast.LENGTH_LONG).show();
						}
		        	}
		        	else if(msg.what==-1){
						//token/auth error
		        		Log.d("Calendar", "invalid token");
						myProgressDialog.dismiss();
						Toast.makeText(ServiceCalendar.this, getString(R.string.autentication_error), Toast.LENGTH_LONG).show();
						setResult(2);
						InternalStorage.goLoggin(ServiceCalendar.this);
					}
		        	else if(msg.what==20){
		        		//carregar novo ano
		        		Webservice w = Webservice.getInstance();
		        		dayloaded.set(GregorianCalendar.YEAR, dayloaded.get(GregorianCalendar.YEAR)+1);
		        		
		        		try{
		        		Disponibilidades.serviceBusyDays=w.getDisponibilidadeAnual(dayloaded.get(GregorianCalendar.YEAR), servico.getId());
		        		}catch(Exception e){e.printStackTrace();}
		        		onTouch(null);
		        		
		        	}
		        	else if(msg.what==21){
		        		//carregar ano anterior
		        		Webservice w = Webservice.getInstance();
		        		dayloaded.set(GregorianCalendar.YEAR, dayloaded.get(GregorianCalendar.YEAR)-1);
		        		
		        		try{
		        		Disponibilidades.serviceBusyDays=w.getDisponibilidadeAnual(dayloaded.get(GregorianCalendar.YEAR), servico.getId());
		        		}catch(Exception e){e.printStackTrace();}
		        		onTouch(null);
		        		
		        	}
					else{
						//connection error
						Log.d("Calendar", "connection error");
						myProgressDialog.dismiss();
						Toast.makeText(ServiceCalendar.this, getString(R.string.impossiblereachtheserver), Toast.LENGTH_LONG).show();		        		
					}
		        	
		        	
		        }
		    };
		}
	}
	/****f* ServiceCalendar/onTouch
	 * DESCRIPTION
	 * Método executado para receber as células carregadas
	 * INPUTS
	 * Célula do calendario
	 * RESULT
	 * Trata a Celula clicada
	 *
	 ****
	 */
	public void onTouch(Cell cell) {
		if(cell!=null){
			day = cell.getDayOfMonth();
			month = mView.getMonth();
			year = mView.getYear();
			
			if(mView.isLastMonth(cell)){
				//update view
		        mView.previousMonth();
		        if(dayloaded.get(GregorianCalendar.YEAR)==mView.getYear()){
					//onTouch(null);
				}
				else{
					//caregar ano anterior  de disponibilidades
					messages.sendEmptyMessage(21);
					return;
				}
		        
			}
			else if(mView.isNextMonth(cell)){
				//update view
				mView.nextMonth();
				if(dayloaded.get(GregorianCalendar.YEAR)==mView.getYear()){
					//onTouch(null);
				}
				else{
					//caregar novo ano de disponibilidades
					messages.sendEmptyMessage(20);
					return;
				}
			}	
			else {
				
				myProgressDialog = ProgressDialog.show(ServiceCalendar.this, getString(R.string.loading), getString(R.string.getDayView), true);			
				new Thread() {

					@Override
					public void run() {
						
						try {
							
							Webservice w = Webservice.getInstance();
							slots=w.GetAppointments();
							
							
							if(slots!=null && slots.size()>0)
							InternalStorage.saveAppointments(slots);
							
							Log.d("Calendar get appointments", "number: "+slots.size());
						}catch (InvalidOAuthTokenError e) {
							messages.sendEmptyMessage(-1);
							Log.d("Calendar", "token error loading bookmarks");
							return;
						}catch (InvalidOAuthParametersError e) {
							messages.sendEmptyMessage(-1);
							Log.d("Calendart", "autentication error loading bookmarks");
							return;
						} 
						catch (Exception e) {
							if(slots==null || slots.size()<=0){
								 try{
							        	slots=InternalStorage.readAppointments();
							        	offline=true;
							        }catch (Exception ex)
							        {
							        Log.d("Offline Favorites", e.toString());
							        }
								 
							}
							if(slots==null || slots.size()<=0){
							messages.sendEmptyMessage(-2);
							Log.d("Favorites", "error loading Favorites");
							return;
							}
						} 
						myProgressDialog.dismiss();
						messages.sendEmptyMessage(1);
					
					}

					}.start();
					
					
			
			}
			}
		/**
		 * swipe next month test if has availabilities
		 */
		if(mView.swipedNext){
			mView.swipedNext=false;
			if(dayloaded.get(GregorianCalendar.YEAR)==mView.getYear()){
				//onTouch(null);
			}
			else{
				//caregar novo ano de disponibilidades
				messages.sendEmptyMessage(20);
				return;
			}
			
		}
		/**
		 * swipe previeus month test if has availabilities
		 */
		else if (mView.swipePrev){
			mView.swipePrev=false;
			if(dayloaded.get(GregorianCalendar.YEAR)==mView.getYear()){
			}
			else{
				//caregar ano anterior  de disponibilidades
				messages.sendEmptyMessage(21);
				return;
			}	
			
		}
		actualMonthTitle.setText(monthName[mView.getMonth()]+", "+mView.getYear());
		MonthDisplayHelper calendarAux = new MonthDisplayHelper(mView.getYear(), mView.getMonth());
        calendarAux.previousMonth();
        calendarAux.nextMonth();
        calendarAux.nextMonth();
        
	}
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		Log.d("ServicoCalendar result", "req "+requestCode+" res "+resultCode);
		super.onActivityResult(requestCode, resultCode, data);   
		if(resultCode==5){
			//finish propositado
			finish();
		}
		if(resultCode==4){
			//finish propositado
			setResult(4);
			finish();
			
		}
	}
 
}
